﻿
namespace n_MidPortList
{
using System;
using System.Drawing;
using System.Drawing.Drawing2D;

using n_MyObject;
using n_MyFileObject;
using n_Shape;
using n_GUIset;
using n_EventIns;
using n_HardModule;

//*****************************************************
//节点链接记录器
public class MidPortList
{
	MidPort[][] PortList;
	int[] LengthList;
	Port[] StartPortList;
	Port[] EndPortList;
	//int[] TypeList;
	int Length;
	
	const int MaxNumber = 30;
	
	/*
	int LastX;
	int LastY;
	float PSX;
	float PSY;
	*/
	
	const int R = 6;
	const int R2 = R * 2;
	const int RN = 30;
	
	bool ExistMouseNear;
	public MidPort MouseOnMidPort;
	
	//构造函数
	public MidPortList()
	{
		PortList = new MidPort[200][];
		LengthList = new int[200];
		StartPortList = new Port[200];
		EndPortList = new Port[200];
		//TypeList = new int[200];
		Length = 0;
		
		ExistMouseNear = false;
		MouseOnMidPort = null;
	}
	
	//显示
	public void Draw( Graphics g )
	{
		if( G.CGPanel.HideLine != 0 ) {
			return;
		}
		for( int i = 0; i < Length; ++i ) {
			if( PortList[i] == null ) {
				continue;
			}
			for( int j = 0; j < LengthList[i]; ++j ) {
				
				if( PortList[i][j].MouseOn ) {
					float midx = PortList[i][j].X;
					float midy = PortList[i][j].Y;
					g.DrawLine( Pens.DarkGray, midx - 2000, midy, midx + 2000, midy );
					g.DrawLine( Pens.DarkGray, midx, midy - 2000, midx, midy + 2000 );
				}
				if( PortList[i][j].MousePress ) {
					float midx = PortList[i][j].X;
					float midy = PortList[i][j].Y;
					g.DrawLine( Pens.Orange, midx - 2000, midy, midx + 2000, midy );
					g.DrawLine( Pens.Orange, midx, midy - 2000, midx, midy + 2000 );
				}
				
				if( n_MainSystemData.SystemData.isBlack ) {
					if( ExistMouseNear ) {
						float midx = PortList[i][j].X;
						float midy = PortList[i][j].Y;
						g.DrawEllipse( Pens.LightGray, midx - R, midy - R, R2, R2 );
					}
					
					if( PortList[i][j].MouseOn ) {
						float midx = PortList[i][j].X;
						float midy = PortList[i][j].Y;
						g.FillEllipse( Brushes.Orange, midx - R, midy - R, R2, R2 );
						g.DrawEllipse( Pens.Yellow, midx - R, midy - R, R2, R2 );
					}
					else if( PortList[i][j].MouseNear ) {
						float midx = PortList[i][j].X;
						float midy = PortList[i][j].Y;
						g.FillEllipse( Brushes.LightGray, midx - R, midy - R, R2, R2 );
						g.DrawEllipse( Pens.WhiteSmoke, midx - R, midy - R, R2, R2 );
					}
					else {
						//...
					}
				}
				else {
					if( ExistMouseNear ) {
						float midx = PortList[i][j].X;
						float midy = PortList[i][j].Y;
						g.DrawEllipse( Pens.DarkSlateGray, midx - R, midy - R, R2, R2 );
					}
					
					if( PortList[i][j].MouseOn ) {
						float midx = PortList[i][j].X;
						float midy = PortList[i][j].Y;
						g.FillEllipse( Brushes.Orange, midx - R, midy - R, R2, R2 );
						g.DrawEllipse( Pens.Red, midx - R, midy - R, R2, R2 );
					}
					else if( PortList[i][j].MouseNear ) {
						float midx = PortList[i][j].X;
						float midy = PortList[i][j].Y;
						g.FillEllipse( Brushes.LightSlateGray, midx - R, midy - R, R2, R2 );
						g.DrawEllipse( Pens.DarkSlateGray, midx - R, midy - R, R2, R2 );
					}
					else {
						//...
					}
				}
				if( PortList[i][j].MultPort > 1 ) {
					float midx = PortList[i][j].X;
					float midy = PortList[i][j].Y;
					g.FillEllipse( Brushes.DarkRed, midx - R + 2, midy - R + 2, R2 - 4, R2 - 4 );
				}
			}
			/*
			try {
				g.DrawLine( Pens.Red, StartPortList[i].Owner.MidX + StartPortList[i].X, StartPortList[i].Owner.MidY + StartPortList[i].Y, EndPortList[i].Owner.MidX + EndPortList[i].X, EndPortList[i].Owner.MidY + EndPortList[i].Y );
			}
			catch{}
			*/
		}
	}
	
	//鼠标移动事件
	public void MouseMove( int mX, int mY )
	{
		if( G.CGPanel.HideLine != 0 ) {
			return;
		}
		ExistMouseNear = false;
		MouseOnMidPort = null;
		
		for( int i = 0; i < Length; ++i ) {
			if( PortList[i] == null ) {
				continue;
			}
			for( int j = 0; j < LengthList[i]; ++j ) {
				PortList[i][j].MultPort = 0;
			}
		}
		
		for( int i = 0; i < Length; ++i ) {
			if( PortList[i] == null ) {
				continue;
			}
			for( int j = 0; j < LengthList[i]; ++j ) {
				
				PortList[i][j].MultPort++;
				
				if( PortList[i][j].MousePress ) {
					ExistMouseNear = true;
					
					//PortList[i][j].X += mX - LastX;
					//PortList[i][j].Y += mY - LastY;
					
					//PortList[i][j].X = PSX + (mX - LastX);
					//PortList[i][j].Y = PSY + (mY - LastY);
					
					PortList[i][j].X = mX;
					PortList[i][j].Y = mY;
					
					bool xok = false;
					bool yok = false;
					
					if( j == 0 && StartPortList[i] != null && Math.Abs( PortList[i][j].X - (StartPortList[i].Owner.MidX + StartPortList[i].X) ) <= 10 ) {
						PortList[i][j].X = StartPortList[i].Owner.MidX + StartPortList[i].X;
						xok = true;
					}
					if( j == 0 && StartPortList[i] != null && Math.Abs( PortList[i][j].Y - (StartPortList[i].Owner.MidY + StartPortList[i].Y) ) <= 10 ) {
						PortList[i][j].Y = StartPortList[i].Owner.MidY + StartPortList[i].Y;
						yok = true;
					}
					
					if( j == LengthList[i] - 1 && EndPortList[i] != null && Math.Abs( PortList[i][j].X - (EndPortList[i].Owner.MidX + EndPortList[i].X) ) <= 10 ) {
						PortList[i][j].X = EndPortList[i].Owner.MidX + EndPortList[i].X;
						xok = true;
					}
					if( j == LengthList[i] - 1 && EndPortList[i] != null && Math.Abs( PortList[i][j].Y - (EndPortList[i].Owner.MidY + EndPortList[i].Y) ) <= 10 ) {
						PortList[i][j].Y = EndPortList[i].Owner.MidY + EndPortList[i].Y;
						yok = true;
					}
					
					if( n_HardModule.Port.C_Rol == 0 ) {
						if( !xok ) {
							PortList[i][j].X = n_Common.Common.GetCrossValue( PortList[i][j].X );
						}
						if( !yok ) {
							PortList[i][j].Y = n_Common.Common.GetCrossValue( PortList[i][j].Y );
						}
					}
					
					//更新拾取对象
					G.CGPanel.TakeMoIndex = -1;
					G.CGPanel.TakePoIndex = -1;
				}
				else {
					float midx = PortList[i][j].X;
					float midy = PortList[i][j].Y;
					if( mX >= midx - R && mX < midx + R && mY >= midy - R && mY < midy + R ) {
						PortList[i][j].MouseOn = true;
						ExistMouseNear = true;
						
						MouseOnMidPort = PortList[i][j];
						
						//更新拾取对象
						G.CGPanel.TakeMoIndex = -1;
						G.CGPanel.TakePoIndex = -1;
					}
					else {
						PortList[i][j].MouseOn = false;
					}
					if( mX >= midx - R - RN && mX < midx + R + RN && mY >= midy - R - RN && mY < midy + R + RN ) {
						PortList[i][j].MouseNear = true;
						ExistMouseNear = true;
					}
					else {
						PortList[i][j].MouseNear = false;
					}
				}
			}
		}
		//LastX = mX;
		//LastY = mY;
	}
	
	//鼠标左键按下事件
	public bool LeftMouseDown( int mX, int mY )
	{
		if( G.CGPanel.HideLine != 0 ) {
			return false;
		}
		//LastX = mX;
		//LastY = mY;
		
		for( int i = Length - 1; i >= 0; --i ) {
			if( PortList[i] == null ) {
				continue;
			}
			for( int j = LengthList[i] - 1; j >= 0; --j ) {
				if( PortList[i][j].MouseOn ) {
					PortList[i][j].MousePress = true;
					//PSX = PortList[i][j].X;
					//PSY = PortList[i][j].Y;
					return true;
				}
			}
		}
		return false;
	}
	
	//鼠标左键松开事件
	public void LeftMouseUp( int mX, int mY )
	{
		if( G.CGPanel.HideLine != 0 ) {
			return;
		}
		for( int i = 0; i < Length; ++i ) {
			if( PortList[i] == null ) {
				continue;
			}
			for( int j = 0; j < LengthList[i]; ++j ) {
				PortList[i][j].MousePress = false;
			}
		}
	}
	
	//鼠标右键按下事件
	public bool RightMouseDown( int mX, int mY )
	{
		if( G.CGPanel.HideLine != 0 ) {
			return false;
		}
		for( int i = Length - 1; i >= 0; --i ) {
			if( PortList[i] == null ) {
				continue;
			}
			for( int j = LengthList[i] - 1; j >= 0; --j ) {
				if( PortList[i][j].MouseOn ) {
					
					for( int x = j; x < LengthList[i] - 1; ++x ) {
						PortList[i][x] = PortList[i][x + 1];
					}
					LengthList[i]--;
					
					if( LengthList[i] == 0 ) {
						
						//这里加了判断是因为LINE引出的主板端口,添加拖点后再右键删除报错null,暂时没有找到问题所在
						if( StartPortList[i] != null ) {
							StartPortList[i].MidPortIndex = -1;
						}
						
						Delete( i );
					}
					
					return true;
				}
			}
		}
		return false;
	}
	
	//设置指定序列, 载入文本程序解析时调用此函数
	public void SetList( int index )
	{
		PortList[index] = new MidPort[MaxNumber];
		LengthList[index] = 0;
		if( Length <= index ) {
			Length = index + 1;
		}
	}
	
	//准备转换
	public void StartSwitch()
	{
		for( int i = 0; i < Length; ++i ) {
			if( PortList[i] == null ) {
				continue;
			}
			for( int j = 0; j < LengthList[i]; ++j ) {
				PortList[i][j].isFirstMult = true;
			}
		}
	}
	
	//添加新的节点系列
	public int AddList()
	{
		for( int i = 0; i < Length; ++i ) {
			if( PortList[i] == null ) {
				PortList[i] = new MidPort[MaxNumber];
				LengthList[i] = 0;
				//TypeList[i] = type;
				return i;
			}
		}
		PortList[Length] = new MidPort[MaxNumber];
		LengthList[Length] = 0;
		//TypeList[Length] = type;
		Length++;
		return Length - 1;
	}
	
	//清空节点列表
	public void Delete( int index )
	{
		PortList[index] = null;
		LengthList[index] = 0;
		StartPortList[index] = null;
		EndPortList[index] = null;
	}
	
	//设置节点列表的起始和终点
	public void SetPort( int index, Port start, Port end )
	{
		StartPortList[index] = start;
		EndPortList[index] = end;
	}
	
	//添加一个端口
	public bool Add( int index, int x, int y )
	{
		if( LengthList[index] < PortList[index].Length ) {
			
			//LastX = x;
			//LastY = y;
			
			float maxcos = -1;
			int maxi = -2;
			int length = LengthList[index];
			
			//判断导线的终点是否是悬空的
			bool nullend = false;
			if( EndPortList[index] == null ) {
				length--;
				nullend = true;
			}
			
			for( int i = -1; i < length; ++i ) {
				
				float x0;
				float y0;
				if( i == -1 ) {
					x0 = StartPortList[index].Owner.MidX + StartPortList[index].X;
					y0 = StartPortList[index].Owner.MidY + StartPortList[index].Y;
				}
				else {
					x0 = PortList[index][i].X;
					y0 = PortList[index][i].Y;
				}
				
				float mmx;
				float mmy;
				if( i == length - 1 && !nullend ) {
					mmx = EndPortList[index].Owner.MidX + EndPortList[index].X;
					mmy = EndPortList[index].Owner.MidY + EndPortList[index].Y;
				}
				else {
					mmx = PortList[index][i+1].X;
					mmy = PortList[index][i+1].Y;
				}
				float mx = mmx - x0;
				float my = mmy - y0;
				float ux = x - x0;
				float uy = y - y0;
				float r1 = (float)Math.Sqrt( ux * ux + uy * uy );
				float r2 = (float)Math.Sqrt( mx * mx + my * my );
				
				//这里不知道为啥... 不加length!=0 那么会有顺序小问题 r1>r2这个判断在曲线上效果不太好, 先这样吧
				if( r1 > r2 && length != 0 ) {
					continue;
				}
				float nj = mx * ux + my * uy;
				float cos = (float)( nj / (r1 * r2) );
				if( cos > maxcos ) {
					maxcos = cos;
					maxi = i;
				}
			}
			
			for( int i = LengthList[index] - 1; i > maxi && i >= 0; --i ) {
				try {
					PortList[index][i + 1] = PortList[index][i];
				}
				catch {
					n_OS.VIO.Show( i + ", " + maxi + "   " + LengthList[index] );
				}
			}
			LengthList[index]++;
			
			if( maxi == -2 ) {
				LengthList[index]--;
				n_OS.VIO.Show( "遇到了一个异常情况: 无法找到最优端口 " + length + "," + LengthList[index] );
				return false;
			}
			MidPort mp = new MidPort( x, y );
			
			MouseOnMidPort = mp;
			mp.MousePress = true;
			mp.MouseOn = true;
			mp.MouseNear = true;
			//PSX = mp.X;
			//PSY = mp.Y;
			
			mp.ListIndex = index;
			mp.Index = maxi + 1;
			PortList[index][maxi + 1] = mp;
			
			return true;
		}
		return false;
	}
	
	//节点翻转
	public void Swap( int index )
	{
		int L = LengthList[index];
		for( int i = 0; i < L/2; ++i) {
			MidPort mp = PortList[index][L - i - 1];
			PortList[index][L - i - 1] = PortList[index][i];
			PortList[index][i] = mp;
		}
	}
	
	//获取节点
	public MidPort GetPoint( int index, int i )
	{
		return PortList[index][i];
	}
	
	//获取节点长度
	public int GetLength( int index )
	{
		return LengthList[index];
	}
	
	//添加节点
	public bool AddPort( int index, float x, float y )
	{
		try {
		if( LengthList[index] < PortList[index].Length ) {
			
			if( MouseOnMidPort != null ) {
					
					if( G.CGPanel.myModuleList.SelectPort.FuncName != n_GUIcoder.PortFuncName.VCC &&
					    G.CGPanel.myModuleList.SelectPort.FuncName != n_GUIcoder.PortFuncName.VCC3_3V &&
					    G.CGPanel.myModuleList.SelectPort.FuncName != n_GUIcoder.PortFuncName.VCC6t9V &&
					    G.CGPanel.myModuleList.SelectPort.FuncName != n_GUIcoder.PortFuncName.GND ) {
						n_Debug.Warning.WarningMessage = ( "仅允许电源正负极导线连接到其他导线上" );
						return false;
					}
					if( G.CGPanel.myModuleList.SelectPort.FuncName == n_GUIcoder.PortFuncName.VCC &&
					    StartPortList[MouseOnMidPort.ListIndex].FuncName != n_GUIcoder.PortFuncName.VCC ) {
						n_Debug.Warning.WarningMessage = ( "电源正极导线仅允许连接到其他正极导线上: " + StartPortList[MouseOnMidPort.ListIndex].FuncName );
						return false;
					}
					if( G.CGPanel.myModuleList.SelectPort.FuncName == n_GUIcoder.PortFuncName.VCC3_3V &&
					    StartPortList[MouseOnMidPort.ListIndex].FuncName != n_GUIcoder.PortFuncName.VCC3_3V ) {
						n_Debug.Warning.WarningMessage = ( "电源正极导线仅允许连接到其他正极导线上: " + StartPortList[MouseOnMidPort.ListIndex].FuncName );
						return false;
					}
					if( G.CGPanel.myModuleList.SelectPort.FuncName == n_GUIcoder.PortFuncName.VCC6t9V &&
					    StartPortList[MouseOnMidPort.ListIndex].FuncName != n_GUIcoder.PortFuncName.VCC6t9V ) {
						n_Debug.Warning.WarningMessage = ( "电源正极导线仅允许连接到其他正极导线上: " + StartPortList[MouseOnMidPort.ListIndex].FuncName );
						return false;
					}
					if( G.CGPanel.myModuleList.SelectPort.FuncName == n_GUIcoder.PortFuncName.GND &&
					    StartPortList[MouseOnMidPort.ListIndex].FuncName != n_GUIcoder.PortFuncName.GND ) {
						n_Debug.Warning.WarningMessage = ( "电源负极导线仅允许连接到其他负极导线上: " + StartPortList[MouseOnMidPort.ListIndex].FuncName );
						return false;
					}
				PortList[index][LengthList[index]] = MouseOnMidPort;
			}
			else {
				PortList[index][LengthList[index]] = new MidPort( x, y );
			}
			
			LengthList[index]++;
		}
		} catch {
			System.Windows.Forms.MessageBox.Show( index.ToString() );
		}
		return MouseOnMidPort != null;
	}
	
	//添加存在的节点
	public bool AddExistPort( int index, int listi, int i )
	{
		try {
		if( LengthList[index] < PortList[index].Length ) {
			
			PortList[index][LengthList[index]] = PortList[listi][i];
			
			LengthList[index]++;
		}
		} catch {
			System.Windows.Forms.MessageBox.Show( index.ToString() );
		}
		return MouseOnMidPort != null;
	}
}
//过渡点链接节点
public class MidPort
{
	public float X;
	public float Y;
	
	public int MultPort;
	
	public bool MouseNear;
	public bool MouseOn;
	public bool MousePress;
	
	public bool isFirstMult;
	
	public int ListIndex;
	public int Index;
	
	//构造函数
	public MidPort( float x, float y )
	{
		MouseNear = false;
		MouseOn = false;
		MousePress = false;
		MultPort = 0;
		X = x;
		Y = y;
		
		ListIndex = -1;
		Index = -1;
	}
}
}



